package com.xxx.userservice.service.impl;

import com.xxx.userservice.pojo.entity.User;
import com.xxx.userservice.mapper.UserMapper;
import com.xxx.userservice.service.UserService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import io.seata.rm.tcc.api.BusinessActionContext;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author guwq
 * @since 2025-05-22
 */
@Slf4j
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {

    @Resource
    private UserMapper userMapper;

    @Override
    public User getByUserId(int userId) {
        return this.lambdaQuery().eq(User::getUserId, userId).one();
    }

    @Override
    public BigDecimal getMoney(String userId) {
        return userMapper.getMoney(userId);
    }

    // TCC模式——Try阶段：业务检查，预留资源
    @Override
    @Transactional   // 使用本地事务
    public boolean prepareDeduct(String userId, BigDecimal amount) {
        log.info("prepareDeduct====================userId:{}, amount:{}", userId, amount);
//        // 判断用户可用余额是否足够
//        BigDecimal money = userMapper.getMoney(userId);
//        if(money == null || money.compareTo(amount) < 0) {
//            log.info("prepareDeduct====================余额不足. userId:{}", userId);
////            return false;  // 返回false并不能代表全局事务会回滚，需要抛出异常才行
//            throw new RuntimeException("余额不足");   // 只有抛出异常，全局事务才会被回滚
//        }

        // 预留资源：冻结可用余额
        boolean result = userMapper.freeze(userId, amount);
        log.info("prepareDeduct====================freeze result:{}", result);

        return result;
    }

    // TCC模式——Confirm阶段：使用Try阶段的预留资源执行业务操作
    @Override
    @Transactional
    public boolean confirm(BusinessActionContext context) {
        String userId = (String) context.getActionContext("userId");
        BigDecimal amount = new BigDecimal(context.getActionContext("amount").toString());
        log.info("confirm====================userId:{}, amount:{}", userId, amount);

        // 实际扣除金额（Confirm阶段）
        boolean result = userMapper.deduct(userId, amount);
        log.info("confirm====================deduct result:{}", result);

        return result;
    }

    // TCC模式——Cancel阶段：取消业务执行，是否Try阶段预留的资源
    @Override
    @Transactional
    public boolean cancel(BusinessActionContext context) {
        String userId = (String) context.getActionContext("userId");
        BigDecimal amount = new BigDecimal(context.getActionContext("amount").toString());
        log.info("cancel====================userId:{}, amount:{}", userId, amount);

        // 释放冻结金额（Cancel阶段）
        boolean result = userMapper.unfreeze(userId, amount);
        log.info("cancel====================unfreeze result:{}", result);

        return result;
    }
}
